package org.example.domain.common.base;

import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

@Data
public abstract class BaseEntity<I extends Serializable> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 逻辑删除字段(0：未删除；主键：已删除)
     */
    private Integer isDeleted;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;

    /**
     * 判断是否为数据库中加载的,延迟加载只对数据库中的对象有效，对新增对象不生效
     */
    protected Boolean loadFlag = false;

    private Set<String> loadSet = new HashSet<>();

    /**
     * 以 OrderEntity 为例 orderItemList 字段为例，延迟加载指的是访问了该字段也就是调用getOrderItemList方法才需要进行加载，
     * 当查询一个 Order 实体时，数据库只返回 Order 相关的数据，并不会进行加载 orderItemList。
     * 延迟加载的字段需要显式调用，不应该由 BeanUtils.copy 自动调用或者 mapstruct 自动调用,否则可能触发重复加载
     * 使用 loadSet 来记录已经加载的字段，避免重复加载
     */
    protected <T> T lazyLoad(String property, PropertyLoader<T> propertyLoader) {
        // 延迟加载只对数据库中的对象有效
        if (loadFlag && !loadSet.contains(property)) {
            propertyLoader.load();
            loadSet.add(property);
        }
        return propertyLoader.get();
    }

    /**
     * 获取主键
     */
    public abstract I getPrimaryId();

    /**
     * 设置主键
     */
    public abstract void setPrimaryId(I id);
}
